package week04.question02;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

/**
 * 本周作业：（必做）思考有多少种方式，在main函数启动一个新线程或线程池，
 * * 异步运行一个方法，拿到这个方法的返回值后，退出主线程？
 * * 写出你的方法，越多越好，提交到github。
 *    方案1 Thread.join()   Happens-Before 6 线程的所有操作先于线程中介
 *    方案2 CountDownLatch()
 *    方案3 Callable + Future
 *    方案4 Runnable + Result + Future
 *    方案5 Runnable + Future
 *    方案6 LockSupport.park / unpark Happens-Before 锁规则
 *    方案7 Semaphore 信号量 Happens-Before 3 volatile规则
 *    方案8 自旋 + interrupt Happens-Before 7 线程中断规则
 */
public class Answer08 {

    public static void main(String[] args) {

        long start = System.currentTimeMillis();

        // 在这里创建一个线程或线程池，
        // 异步执行 下面方法
        ExecutorService executorService = Executors.newFixedThreadPool(1);

        int [] arrays = new int[1];
        Thread mainThread = Thread.currentThread();
        executorService.submit(()->{
            arrays[0]=sum();
            mainThread.interrupt();//中断 当成信号传递出去
        });

        int result = 0; //这是得到的返回值

        for(;;){
            if(Thread.interrupted()){
                break;
            }
        }
        result = arrays[0];


        // 确保  拿到result 并输出
        System.out.println("异步计算结果为：" + result);

        System.out.println("使用时间：" + (System.currentTimeMillis() - start) + " ms");

        // 然后退出main线程
        executorService.shutdown();
    }

    private static int sum() {
        return fibo(36);
    }

    private static int fibo(int a) {
        if (a < 2)
            return 1;
        return fibo(a - 1) + fibo(a - 2);
    }
}
